﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace NJT.Services
{
    public class 反射
    {
        /// <summary>
        /// 调用静态方法
        /// </summary>
        /// <param name="t">类全名</param>
        /// <paramname="方法名">方法名</param>
        /// <paramname="参数表">参数表</param>
        /// <returns>函数返回值</returns>
        public static object 静态方法(System.Type t, string strMethod, object[] aobjParams)
        {
            var eFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

            return 调用方法(t, strMethod, null, aobjParams, eFlags);
        }

        /// <summary>
        /// 调用实例方法
        /// </summary>
        /// <param name="t">类全名</param>
        /// <paramname="方法名">方法名</param>
        /// <paramname="类的实例">类的实例</param>
        ///<paramname="参数表">参数表</param>
        ///<returns>函数返回值</returns>
        public static object 实例方法(System.Type t, string 方法名,
            object 类的实例, object[] 参数表)
        {
            var eFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            return 调用方法(t, 方法名, 类的实例, 参数表, eFlags);
        }


        private static object 调用方法(System.Type t, string strMethod, object objInstance, object[] aobjParams,
            BindingFlags eFlags)
        {
            MethodInfo m;

            try
            {
                m = t.GetMethod(strMethod, eFlags);

                if (m == null)
                {
                    throw new ArgumentException("这不是函数 '" + strMethod + "' 在类型 '" + t.ToString() + "'.");
                }

                var objRet = m.Invoke(objInstance, aobjParams);
                return objRet;
            }

            catch
            {
                throw;
            }
        }

        public static object 读取字段(object 对象, string 字段名)
        {
            var bind = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
            var t = 对象.GetType();
            try
            {
                var fs = t.GetFields(bind);
                var fields = fs.FirstOrDefault(cs => cs.Name == 字段名);
                if (fields == null)
                {
                    throw new ArgumentException("字段 '" + 字段名 + "' 不存在. '");
                }
                var objRet = fields.GetValue(对象); //.GetType() m.Invoke(objInstance, aobjParams);
                return objRet;
            }

            catch
            {
                throw;
            }
        }
    }
}
